﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;

using BlueCMS.Core.Data;
using BlueCMS.Core.Data.Query.Clauses;
using BlueCMS.Core.Data.Query.Columns;
using BlueCMS.Core.Data.Query.Conditions;
using BlueCMS.Core.Data.Query.Tables;
using BlueCMS.Core.Providers;

namespace BlueCMS.Core.Data.Query.Generator
{
    public abstract partial class QueryGeneratorBase
    {
        public virtual string ProcessInsertQuery(InsertClause insert, ValuesClause values, SelectQuery query, Dictionary<string, DbParameter> parameters)
        {
            StringBuilder sb = new StringBuilder();

            if (values.ValueColumns.Count > 0 && query != null)
            {
                throw new QueryException("Insert statements cannot include both and VALUES(...) and SELECT statement");
            }
            if (values.ValueColumns.Count == 0 && query == null)
            {
                throw new QueryException("Insert statements must include a VALUES(...) or SELECT statement");
            }

            GenerateInsertStatement(insert, sb);
            if (query != null)
            {
                GenerateSelect(query, sb);
            }
            else
            {
                GenerateInsertValues(values, sb, parameters);
            }

            return sb.ToString();
        }

        protected virtual void GenerateInsertStatement(InsertClause clause, StringBuilder sb)
        {
            sb.Append("INSERT INTO ");
            GenerateTableName(clause.InsertTable, sb);
            if (clause.InsertColumns.Count > 0)
            {
                sb.Append("(");
                foreach (InsertColumn column in clause.InsertColumns)
                {
                    GenerateColumnName((string)column.NameOrExpression, sb);
                    sb.Append(", ");
                }
                sb.Remove(sb.Length - 2, 2);
                sb.Append(")");
            }
        }

        protected virtual void GenerateInsertValues(ValuesClause clause, StringBuilder sb, Dictionary<string, DbParameter> parameters)
        {
            sb.Append(" VALUES(");
            foreach (ValueColumn column in clause.ValueColumns)
            {
                switch (column.Type)
                {
                    case InsertType.Constant:
                        GenerateConstant(column.NameOrExpression, sb);
                        break;
                    case InsertType.Parameter:
                        GenerateParameter(column.NameOrExpression, sb, parameters);
                        break;
                }
                sb.Append(", ");
            }
            sb.Remove(sb.Length - 2, 2);
            sb.Append(")");
        }
    }
}
